import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router';
import type { App, Plugin } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';

import { unref } from 'vue';
import { isObject } from '/@/utils/is';
import { cloneDeep } from 'lodash-es';

const { createMessage } = useMessage();

export const noop = () => {};

/**
 * @description:  Set ui mount node
 */
export function getPopupContainer(node?: HTMLElement): HTMLElement {
  return (node?.parentNode as HTMLElement) ?? document.body;
}

/**
 * Add the object as a parameter to the URL
 * @param baseUrl url
 * @param obj
 * @returns {string}
 * eg:
 *  let obj = {a: '3', b: '4'}
 *  setObjToUrlParams('www.baidu.com', obj)
 *  ==>www.baidu.com?a=3&b=4
 */
export function setObjToUrlParams(baseUrl: string, obj: any): string {
  let parameters = '';
  for (const key in obj) {
    parameters += key + '=' + encodeURIComponent(obj[key]) + '&';
  }
  parameters = parameters.replace(/&$/, '');
  return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters;
}

// 深度合并
export function deepMerge<T = any>(src: any = {}, target: any = {}): T {
  let key: string;
  const res: any = cloneDeep(src);
  for (key in target) {
    res[key] = isObject(res[key]) ? deepMerge(res[key], target[key]) : (res[key] = target[key]);
  }
  return res;
}

export function openWindow(
  url: string,
  opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean },
) {
  const { target = '__blank', noopener = true, noreferrer = true } = opt || {};
  const feature: string[] = [];

  noopener && feature.push('noopener=yes');
  noreferrer && feature.push('noreferrer=yes');

  window.open(url, target, feature.join(','));
}

// dynamic use hook props
export function getDynamicProps<T, U>(props: T): Partial<U> {
  const ret: Recordable = {};

  Object.keys(props).map((key) => {
    ret[key] = unref((props as Recordable)[key]);
  });

  return ret as Partial<U>;
}

export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized {
  if (!route) return route;
  const { matched, ...opt } = route;
  return {
    ...opt,
    matched: (matched
      ? matched.map((item) => ({
          meta: item.meta,
          name: item.name,
          path: item.path,
        }))
      : undefined) as RouteRecordNormalized[],
  };
}

export const withInstall = <T>(component: T, alias?: string) => {
  const comp = component as any;
  comp.install = (app: App) => {
    app.component(comp.name || comp.displayName, component);
    if (alias) {
      app.config.globalProperties[alias] = component;
    }
  };
  return component as T & Plugin;
};

/**
 * 获取error错误
 */
export function getFormErrorMessage(form) {
  // 提示第一个error
  if (form.errorFields) {
    for (let index = 0; index < form.errorFields.length; index++) {
      const ruleField = form.errorFields[index];
      if (ruleField.errors.length > 0) {
        createMessage.error(ruleField.errors[0]);
        break;
      }
    }
  }
}

/**
 * 文本长度校验
 */
export function checkTextLength(str, num) {
  // 先获取中文
  const reg = /[\u4e00-\u9fa5]/g;
  const cnStrs = str.match(reg);
  const cnStr = cnStrs && cnStrs instanceof Array ? cnStrs.join('') : '';
  // 获取除中文以外其他字符长度
  const otherStrLength = str.length - cnStr.length;
  // 计算总长度
  const totalLength = otherStrLength + cnStr.length * 8;
  return totalLength > num;
}
/**
 * 名称校验
 */
export function checkName(value, label) {
  if (['', null, undefined].indexOf(value) >= 0) {
    /* eslint-disable-next-line */
    return Promise.reject('请输入' + label);
  }
  const firstVal = value[0];
  if ('0123456789_'.indexOf(firstVal) >= 0) {
    /* eslint-disable-next-line */
    return Promise.reject('只允许字母和中文开头');
  }
  const reg = /^[\u4e00-\u9fa5_a-zA-Z0-9]+$/;
  if (!reg.test(value)) {
    /* eslint-disable-next-line */
    return Promise.reject('不能包含特殊字符');
  }
  if (checkTextLength(value, 200)) {
    return Promise.reject('长度大于200，请重新输入');
  }
  return Promise.resolve();
}
/**
 * 名称校验
 */
export function checkNameByTable(value, label, list) {
  if (['', null, undefined].indexOf(value) >= 0) {
    /* eslint-disable-next-line */
    return '请输入' + label;
  }
  const firstVal = value[0];
  if ('0123456789_'.indexOf(firstVal) >= 0) {
    /* eslint-disable-next-line */
    return '只允许字母和中文开头';
  }
  const reg = /^[\u4e00-\u9fa5_a-zA-Z0-9]+$/;
  if (!reg.test(value)) {
    /* eslint-disable-next-line */
    return '不能包含特殊字符';
  }
  if (checkTextLength(value, 200)) {
    return '长度大于200，请重新输入';
  }
  if (list.filter((item) => item.AlarmStringType === value).length >= 2) {
    return `存在相同的${label}(${value})，请重新输入`;
  }
  return '';
}
/**
 * ip校验
 */
export function checkIp(value, label, isChecked = true) {
  if (['', null, undefined].indexOf(value) >= 0 && isChecked) {
    return Promise.reject('请输入' + label);
  }

  const reg =
    /^((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(?::(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5]))?$/;
  if (!reg.test(value) && isChecked) {
    return Promise.reject('格式有误，请重新输入');
  }

  return Promise.resolve();
}

/**
 * 空校验
 */
export function checkVaid(value, msg, isChecked = true) {
  if (['', null, undefined].indexOf(value) >= 0 && isChecked) {
    return Promise.reject(msg);
  }
  return Promise.resolve();
}
/**
 * 获取访问图片域名
 */
export function getUrlProfix() {
  const imgUrl = sessionStorage.getItem('imgUrl');
  let url = 'http://localhost:8055/';
  if (imgUrl) {
    url = imgUrl;
  }

  if (process.env.NODE_ENV === 'production') {
    const loaclhostNames = window.location.href.split('/');
    // 如果配置访问url则取配置文件的
    const WebAppUrl = sessionStorage.getItem('WebAppUrl');
    if (WebAppUrl) {
      url = `${WebAppUrl}/`;
    } else if (loaclhostNames?.length > 0 && loaclhostNames[2]) {
      const domain = loaclhostNames[2].split(':')[0];
      url = `http://${domain}:8088/`;
    }
  }
  return url;
}
